package com.lagou.handler;

import com.lagou.proto.RpcResponse;
import io.netty.channel.Channel;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class ResponseFuture {

    private final String requestId;

    private final long timeoutMillis;

    private volatile boolean sendRequestOK = true;

    private final long beginTimestamp = System.currentTimeMillis();

    private final CountDownLatch countDownLatch = new CountDownLatch(1);

    private volatile Throwable cause;

    private volatile RpcResponse rpcResponse;

    private Class resultClass;

    public ResponseFuture(String requestId, long timeoutMillis, Class resultClass) {
        this.requestId = requestId;
        this.timeoutMillis = timeoutMillis;
        this.resultClass = resultClass;
    }


    public boolean isTimeout() {
        long diff = System.currentTimeMillis() - this.beginTimestamp;
        return diff > this.timeoutMillis;
    }

    public RpcResponse waitResponse(final long timeoutMillis) throws InterruptedException {
        this.countDownLatch.await(timeoutMillis, TimeUnit.MILLISECONDS);
        return this.rpcResponse;
    }

    public void putResponse(final RpcResponse rpcResponse) {
        this.rpcResponse = rpcResponse;
        this.countDownLatch.countDown();
    }

    public long getBeginTimestamp() {
        return beginTimestamp;
    }

    public boolean isSendRequestOK() {
        return sendRequestOK;
    }

    public void setSendRequestOK(boolean sendRequestOK) {
        this.sendRequestOK = sendRequestOK;
    }

    public long getTimeoutMillis() {
        return timeoutMillis;
    }

    public String getRequestId() {
        return requestId;
    }

    public CountDownLatch getCountDownLatch() {
        return countDownLatch;
    }

    public Throwable getCause() {
        return cause;
    }

    public void setCause(Throwable cause) {
        this.cause = cause;
    }

    public RpcResponse getRpcResponse() {
        return rpcResponse;
    }

    public void setRpcResponse(RpcResponse rpcResponse) {
        this.rpcResponse = rpcResponse;
    }

    public Class getResultClass() {
        return resultClass;
    }

    public void setResultClass(Class resultClass) {
        this.resultClass = resultClass;
    }
}
